using System;
using System.Collections.Specialized;
using System.IO;

namespace FileDirUtils
{
    public class DirFilesGetter
    {       
        private readonly bool recursive;
        StringCollection files = new StringCollection();      

        private IFilter posFileFilter;
        private IFilter negFileFilter;
        private IFilter posDirFilter;
        private IFilter negDirFilter;

        public IFilter PosFileFilter
        {
            set { posFileFilter = value; }
            get { return posFileFilter; }
        }
        public IFilter NegFileFilter
        {
            set { negFileFilter = value; }
            get { return negFileFilter; }
        }
        public IFilter PosDirFilter
        {
            set { posDirFilter = value; }
            get { return posDirFilter; }
        }
        public IFilter NegDirFilter
        {
            set { negDirFilter = value; }
            get { return negDirFilter; }
        }

        public DirFilesGetter(bool recursive)
        {
            this.recursive = recursive;
        }
        public StringCollection GetFilesFromDir(string dirName)
        {
            AddFilesFromDir(dirName);
            if (recursive)
            {
                foreach (string subDir in GetSubDirs(dirName))
                    GetFilesFromDir(subDir);
            }
            return files;
        }
        private bool DoPosFileFilter(string fullPathName)
        {
            return (posFileFilter == null) ? true : posFileFilter.Match(fullPathName);            
        }
        private bool DoNegFileFilter(string fullPathName)
        {
            return (negFileFilter == null) ? false : negFileFilter.Match(fullPathName);
        }
        private bool DoPosDirFilter(string fullPathName)
        {
            return (posDirFilter == null) ? true : posDirFilter.Match(fullPathName);
        }
        private bool DoNegDirFilter(string fullPathName)
        {
            return (negDirFilter == null) ? false : negDirFilter.Match(fullPathName);
        }
        
        private void AddFilesFromDir(string actDir)
        {
            if (!Directory.Exists(actDir))
                return;

            DirectoryInfo dirInfo = new DirectoryInfo(actDir);
            foreach (FileInfo fi in dirInfo.GetFiles())
            {
                if (DoPosFileFilter(fi.FullName) && !DoNegFileFilter(fi.FullName))
                    files.Add(fi.FullName);
            }
        }

        private StringCollection GetSubDirs(String actDir)
        {
            StringCollection subDirs = new StringCollection();
            DirectoryInfo dirInfo = new DirectoryInfo(actDir);
            foreach(DirectoryInfo di in dirInfo.GetDirectories())
            {
                 if (DoPosDirFilter(di.FullName) && !DoNegDirFilter(di.FullName))
                    subDirs.Add(di.FullName);
            }
            return subDirs;
        }
    }
}